package com.youlu.campus.service.activity.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.ActivityTaskCaDomain;
import com.youlu.campus.entity.VO.req.UserActivityTaskInfoQueryListVO;
import com.youlu.campus.entity.VO.req.UserActivityTaskInfoQueryVO;
import com.youlu.campus.entity.VO.req.UserActivityTaskInfoVerifyReq;
import com.youlu.campus.entity.VO.res.QaRuleMatchRes;
import com.youlu.campus.entity.ca.UserCa;
import com.youlu.campus.entity.ca.UserSubActivity;
import com.youlu.campus.entity.domain.SubsriptionWechatMsg;
import com.youlu.campus.entity.domain.UserActivityTaskInfoDomin;
import com.youlu.campus.entity.dto.sms.SmsBaseInfoDTO;
import com.youlu.campus.entity.english.UserCompetitionQa;
import com.youlu.campus.entity.english.vo.request.QueryQaHomeCommand;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.entity.enums.TaskExecuteType;
import com.youlu.campus.entity.platform.PlatformTaskInfo;
import com.youlu.campus.service.activity.*;
import com.youlu.campus.service.ca.CaGroupInfoService;
import com.youlu.campus.service.ca.UserCaService;
import com.youlu.campus.service.ca.impl.CertificateActivityConfigService;
import com.youlu.campus.service.platform.PointPlatformConfigService;
import com.youlu.campus.service.platform.PointPlatformTaskConfigService;
import com.youlu.campus.service.ranking.UserActivityPointDetailService;
import com.youlu.campus.service.ranking.UserActivityPointRankingProvinceService;
import com.youlu.campus.service.ranking.UserActivityPointRankingService;
import com.youlu.campus.service.ranking.UserPointRankingService;
import com.youlu.campus.service.sms.SmsServerService;
import com.youlu.campus.service.sms.SmsTemplateService;
import com.youlu.campus.service.visitor.UserActivitySubWechatTemplateMsgService;
import com.youlu.campus.service.visitor.UserAppSubWechatTemplateMsgLogService;
import com.youlu.campus.service.visitor.UserAppSubWechatTemplateMsgService;
import com.youlu.campus.service.visitor.UserPointsService;
import com.yuelin.infrastructure.quantum.common.QResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

import static com.youlu.campus.entity.enums.TaskExecuteType.DAILY;

@Slf4j
@Service
public class UserActivityTaskInfoServiceImpl implements UserActivityTaskInfoService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Lazy
    @Autowired
    private ActivityService activityService;
    @Autowired
    private ActivityTaskService activityTaskService;
    @Autowired
    private UserActivityPointRankingService userActivityPointRankingService;
    @Autowired
    private ActivityTaskRuleService activityTaskRuleService;
    @Autowired
    private UserActivitySubWechatTemplateMsgService userActivitySubWechatTemplateMsgService;
    @Autowired
    private UserAppSubWechatTemplateMsgService userAppSubWechatTemplateMsgService;
    @Autowired
    private UserActivityPointRankingProvinceService userActivityPointRankingProvinceService;
    @Autowired
    private UserActivityPointDetailService userActivityPointDetailService;
    @Autowired
    private PointPlatformConfigService pointPlatformConfigService;
    @Autowired
    private UserPointsService userPointsService;
    @Autowired
    private UserPointRankingService userPointRankingService;
    @Autowired
    private UserAppSubWechatTemplateMsgLogService userAppSubWechatTemplateMsgLogService;
    @Autowired
    private PointPlatformTaskConfigService pointPlatformTaskConfigService;

    @Autowired
    private UserParticipateActivityInfoService userParticipateActivityInfoService;
    @Lazy
    @Autowired
    private UserCaService userCaService;
    @Lazy
    @Autowired
    private CaGroupInfoService caGroupInfoService;
    @Lazy
    @Autowired
    private CertificateActivityConfigService certificateActivityConfigService;
    @Lazy
    @Autowired
    private SmsTemplateService smsTemplateService;
    @Autowired
    private SmsServerService smsServerService;

    @Override
    public Page<UserActivityTaskInfo> list(UserActivityTaskInfoQueryListVO req) {
        log.info(":>>> 开始获取用户任务列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || Objects.isNull(req.getPage()) || Objects.isNull(req.getPageSize())) {
            log.error(":>>> 参数错误:分页、页码为空");
            throw new BusinessException("参数错误:分页、页码为空");
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        }
        if (StringUtils.isNotBlank(req.getName())) {
            query.addCriteria(Criteria.where("name").is(req.getName()));
        }
        if (StringUtils.isNotBlank(req.getMobile())) {
            query.addCriteria(Criteria.where("mobile").is(req.getMobile()));
        }
        if (Objects.nonNull(req.getTaskBizType())) {
            query.addCriteria(Criteria.where("taskBizType").is(req.getTaskBizType()));
        }
        if (Objects.nonNull(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, UserActivityTaskInfo.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserActivityTaskInfo> infos = mongoTemplate.find(query.with(pageRequest), UserActivityTaskInfo.class);
        for (UserActivityTaskInfo u : infos) {
            if (StringUtils.isNotBlank(u.getUserId()) && StringUtils.isNotBlank(u.getActivityId()) && Objects.nonNull(u.getTaskBizType())) {
                Query queryPrint = new Query();
                queryPrint.addCriteria(Criteria.where("userId").is(u.getUserId()).and("activityId").is(u.getActivityId())
                        .and("taskBizType").is(u.getTaskBizType().name()));
                queryPrint.limit(10);
                List<UserActivityFootPrint> list = mongoTemplate.find(queryPrint, UserActivityFootPrint.class);
                u.setPrints(list);
            }
            if (StringUtils.isNotBlank(u.getActivityId())) {
                if (!StringUtils.isNotBlank(u.getActivityName())) {
                    ActivityInfo activityInfo = activityService.findOne(u.getActivityId());
                    if (Objects.nonNull(activityInfo)) {
                        u.setActivityName(activityInfo.getName());
                    }
                }
            }
        }
        return PageableExecutionUtils.getPage(infos, pageRequest, () -> count);
    }

    @Override
    public boolean create(@NotNull UserActivityTaskInfo req) {
        req.setId(null);
        req.setCreatedTime(new Date());
        req = mongoTemplate.insert(req);
        if (StringUtils.isNotBlank(req.getId())) {
            return true;
        }

        return false;
    }

    @Override
    public boolean update(@NotNull UserActivityTaskInfo req) {
        log.info(":>>> 开始修改用户活动任务:{}", JSON.toJSONString(req));
        if (StringUtils.isBlank(req.getId())) {
            return false;
        }
        Query query = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        boolean toUpdate = false;
        boolean result = false;
        if (Objects.nonNull(req.getStatus())) {
            update.set("status", req.getStatus());
            toUpdate = true;
        }
        if (toUpdate) {
            update.set("updatedTime", new Date());
            UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserActivityTaskInfo.class);
            result = updateResult.getModifiedCount() > 0 ? true : false;
            log.info(":>>> 修改用户活动任务:{} 结果:{}", req.getId(), result);
        }
        return result;
    }

    @Override
    public boolean delete(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        mongoTemplate.remove(query, UserActivityTaskInfo.class);
        return false;
    }

    @Override
    public UserActivityTaskInfo find(String userId, String activityId, TaskBizType taskBizType, Date day) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("taskBizType").is(taskBizType));
        if (Objects.nonNull(day)) {
            query.addCriteria(Criteria.where("dayTime").is(day));
        }
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public UserActivityTaskInfo find(String userId, String activityId, String taskId, Date day) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("taskId").is(taskId).and("dayTime").is(day));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public UserActivityTaskInfo findTaskByStatus(String userId, String activityId, String taskId, Integer status) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("taskId").is(taskId).and("status").is(status));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public UserActivityTaskInfo findNotReceiveTask(String userId, String activityId, String taskId, List<Integer> status) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("taskId").is(taskId).and("status").nin(status));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public UserActivityTaskInfo find(String userId, String activityId, String taskId) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("taskId").is(taskId));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public UserActivityTaskInfo find(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public List<UserActivityTaskInfoDomin> findBy(UserActivityTaskInfoQueryVO req) {
        String userId = req.getUserId();
        String activityId = req.getActivityId();
        Date dayTime = req.getDayTime();
        log.info(":>>> 开始查找用户:{} 活动:{} 任务列表", userId, activityId);
        ActivityInfo activityInfo = activityService.findOne(activityId);
        if (Objects.isNull(activityInfo)) {
            log.info(":>>> 活动不存在:{}", activityId);
            return new ArrayList<>();
        }
        Query queryTask = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("opened").ne(false).and("deleted").ne(true)).with(Sort.by(Sort.Direction.DESC, "priority"));
        List<ActivityTaskInfo> taskInfos =
                mongoTemplate.find(queryTask, ActivityTaskInfo.class);
        if (CollectionUtils.isEmpty(taskInfos)) {
            log.info(":>>> 活动任务不存在:{}", activityId);
            return new ArrayList<>();
        }
        List<UserActivityTaskInfoDomin> res = new ArrayList<>();
        Query queryAll = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("doType").is("all"));
        List<UserActivityTaskInfo> allDatas = mongoTemplate.find(queryAll, UserActivityTaskInfo.class);
        Query queryDay = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("doType").is("day").and("dayTime").is(dayTime));
        List<UserActivityTaskInfo> dayDatas = mongoTemplate.find(queryDay, UserActivityTaskInfo.class);
        for (ActivityTaskInfo taskInfo : taskInfos) {
            UserActivityTaskInfoDomin domain = new UserActivityTaskInfoDomin();
            BeanUtils.copyProperties(taskInfo, domain);
            domain.setTaskId(taskInfo.getId());
            domain.setTaskBizType(taskInfo.getTaskBizType());
            domain.setOuterLinker(taskInfo.getOuterLinker());
            domain.setOuterLinkerImage(taskInfo.getOuterLinkerImage());
            domain.setAvailableThreshold(taskInfo.getAvailableThreshold());
            // 订阅消息任务
            if (TaskBizType.SUBSCRIPTION.equals(taskInfo.getTaskBizType())) {
                String templateIds = "";
                if (CollectionUtils.isNotEmpty(taskInfo.getWechatTemplateMsgs())) {
                    //模板id优先取活动任务配置
                    for (WechatTemplateMsg msg : taskInfo.getWechatTemplateMsgs()) {
                        if (StringUtils.isBlank(msg.getTemplateId())) {
                            continue;
                        }
                        if (StringUtils.isBlank(templateIds)) {
                            templateIds = msg.getTemplateId();
                        } else {
                            templateIds = templateIds + "," + msg.getTemplateId();
                        }
                    }
                    domain.setTemplateIds(templateIds);
                    domain.setAppId(activityInfo.getWechatAppId());
                }
                if (StringUtils.isEmpty(taskInfo.getTaskExtra())) {
                    //如活动任务未配模板id则取平台任务配置模板id
                    PointPlatformTaskConfigQueryVO pointPlatformTaskConfigQueryVO = new PointPlatformTaskConfigQueryVO();
                    pointPlatformTaskConfigQueryVO.setPlatform(req.getPlatform());
                    pointPlatformTaskConfigQueryVO.setAppId(req.getAppId());
                    pointPlatformTaskConfigQueryVO.setStatus(1);
                    PlatformTaskInfo tmplList = pointPlatformTaskConfigService.findTmplByAppId(pointPlatformTaskConfigQueryVO);
                    if (Objects.nonNull(tmplList)) {
                        templateIds = StringUtils.join(tmplList.getTaskExtra(), ',');
                    }
                    domain.setTaskExtra(templateIds);
                }
            }
            boolean to = true;
            for (UserActivityTaskInfo u : allDatas) {
                if (taskInfo.getId().equals(u.getTaskId())) {
                    log.info(":>>> 任务类型:{},ID:{} 状态为:{}", taskInfo.getTaskBizType(), taskInfo.getId(), u.getStatus());
                    domain.setStatus(u.getStatus());
                    to = false;
                    break;
                }
            }
            if (!to) {
                log.info(":>>> 任务类型:{},ID:{} 状态为:{}", taskInfo.getTaskBizType(), taskInfo.getId(), domain.getStatus());
                res.add(domain);
                continue;
            }
            for (UserActivityTaskInfo u : dayDatas) {
                if (taskInfo.getId().equals(u.getTaskId())) {
                    log.info(":>>> 任务类型:{},ID:{} 状态为:{}", taskInfo.getTaskBizType(), taskInfo.getId(), u.getStatus());
                    domain.setStatus(u.getStatus());
                    break;
                }
            }
            log.info(":>>> 任务类型:{},ID:{} 状态为:{}", taskInfo.getTaskBizType(), taskInfo.getId(), domain.getStatus());
            res.add(domain);
        }
        log.info(":>>> 用户:{} 活动:{} 任务状态:{}", req.getUserId(), req.getActivityId(), JSON.toJSON(res));
        return res;
    }

    @Async
    @Override
    public void createTask(UserActivityTaskInfo taskInfo) {
        if (Objects.isNull(taskInfo) || Objects.isNull(taskInfo.getTaskBizType())) {
            return;
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(taskInfo.getActivityId(), taskInfo.getTaskBizType());
        if (Objects.isNull(activityTaskInfo)) {
            return;
        }
        taskInfo.setCreatedTime(new Date());
        taskInfo.setTaskId(activityTaskInfo.getId());
        this.mongoTemplate.save(taskInfo);
    }

    @Override
    public UserActivityTaskInfo createTaskById(UserActivityTaskInfo taskInfo) {
        if (Objects.isNull(taskInfo) || Objects.isNull(taskInfo.getTaskId())) {
            return null;
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.findOne(taskInfo.getTaskId());
        if (Objects.isNull(activityTaskInfo)) {
            return null;
        }
        UserActivityTaskInfo userActivityTaskInfo = new UserActivityTaskInfo();
        switch (activityTaskInfo.getTaskExecuteType()) {
            case ONCE:
                userActivityTaskInfo = this.find(taskInfo.getUserId(), taskInfo.getActivityId(), taskInfo.getTaskId());
                break;
            case DAILY:
                userActivityTaskInfo = this.findNotReceiveTask(taskInfo.getUserId(), taskInfo.getActivityId(), taskInfo.getTaskId(), Lists.newArrayList(0, 4));
                if (Objects.isNull(userActivityTaskInfo)) {
                    userActivityTaskInfo = this.find(taskInfo.getUserId(), taskInfo.getActivityId(), taskInfo.getTaskId(), TimeUtils.getDayStartTime(new Date()));
                }
                break;
            default:
                break;
        }
        if (Objects.nonNull(userActivityTaskInfo)) {
            return userActivityTaskInfo;
        }
        return this.mongoTemplate.insert(taskInfo);
    }

    @Override
    public UserActivityTaskInfo find(String userId, String activityId, TaskBizType taskBizType) {
        Query query = new Query().addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).and("taskBizType").is(taskBizType));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public boolean join(UserPO userPO, String activityId, TaskBizType taskBizType) {
        UserActivityTaskInfo u = this.find(userPO.getId(), activityId, taskBizType);
        if (Objects.nonNull(u)) {
            return true;
        }
        ActivityTaskInfo taskInfo = activityTaskService.find(activityId, taskBizType);
        if (Objects.isNull(taskInfo)) {
            return true;
        }
        UserActivityTaskInfo userActivityTaskInfo = new UserActivityTaskInfo();
        userActivityTaskInfo.setActivityId(activityId);
        userActivityTaskInfo.setUserId(userPO.getId());
        userActivityTaskInfo.setTaskId(taskInfo.getId());
        userActivityTaskInfo.setDoType("all");
        if (TaskBizType.JOIN_QQ_GROUP.equals(taskBizType) || TaskBizType.SUBSCRIPTION.equals(taskBizType)) {
            userActivityTaskInfo.setStatus(2);
        } else {
            userActivityTaskInfo.setStatus(1);
        }
        userActivityTaskInfo.setTaskBizType(taskBizType);
        this.create(userActivityTaskInfo);
        // 更新排行榜
        ActivityTaskRule taskRule = activityTaskRuleService.find(activityId, taskBizType.name());
        if (Objects.isNull(taskRule)) {
            log.error(":>>> 活动:{} 没有没有配置:{} 任务明细", activityId, taskBizType);
            return false;
        }
        // TODO添加贡献值明细
        // 积分类
        UserActivityPointDetail detail = new UserActivityPointDetail();
        detail.setActivityId(activityId);
        detail.setUserId(userPO.getId());
        detail.setUserPO(userPO);
        detail.setPoints(taskRule.getPoints().intValue());
        detail.setAction("add");
        detail.setBizDesc(taskInfo.getName());
        detail.setTaskId(taskInfo.getId());
        switch (taskBizType) {
            case SUBSCRIPTION:
                detail.setBizType("subscription");
                break;
            case JOIN_QQ_GROUP:
                detail.setBizType("join-qq-group");
                break;
            default:
                break;
        }

        userActivityPointDetailService.create(detail);
        // 更新全国榜
//        userActivityPointRankingService.updatePoint(userPO, activityId, taskRule.getPoints().intValue());
        // 更新省榜
        userActivityPointRankingProvinceService.updatePoint(userPO, activityId, taskRule.getPoints().intValue());
        return true;
    }

    @Override
    public boolean subsriptionWechatMsg(@NotNull SubsriptionWechatMsg req) {
        log.info(":>>> 开始处理订阅消息:{}", JSON.toJSONString(req));
        ActivityTaskInfo taskInfo = null;
        String taskId = "";
        taskInfo = activityTaskService.find(req.getActivityId(), req.getTaskBizType());
        if (Objects.nonNull(taskInfo)) {
            taskId = taskInfo.getId();
        }
        ActivityInfo activityInfo = activityService.findOne(req.getActivityId());
        UserParticipateActivityInfo userParticipateActivityInfo = null;
        if (!"jinshuju".equals(activityInfo.getType())) {
            userParticipateActivityInfo = userParticipateActivityInfoService.findByUserIdActivityId(req.getUserPO().getId(), req.getActivityId());
        }
        Date date = new Date();
        for (String templateId : req.getTemplateIds()) {
            boolean exist = userActivitySubWechatTemplateMsgService.exist(req.getUserPO().getId(), req.getActivityId(), req.getPlatform(), req.getSubAppId(),
                    templateId);
            log.info(":>>> 订阅模版消息,用户:{},活动:{},平台:{},appId:{},模版Id:{},是否存在:{}", req.getUserPO().getId(), req.getActivityId(), req.getPlatform(), req.getAppId(),
                    templateId, exist);
            if (exist) {
                continue;
            }
            UserActivitySubWechatTemplateMsg msg = new UserActivitySubWechatTemplateMsg();
            msg.setActivityId(req.getActivityId());
            // 订阅的appId和openId
            msg.setAppId(req.getSubAppId());
            if (StringUtils.isNotBlank(req.getSubOpenId())) {
                msg.setOpenId(req.getSubOpenId());
            } else {
                msg.setOpenId(req.getUserPO().getOpenId());
            }
            msg.setPlatform(req.getPlatform());
            msg.setTaskId(taskId);
            msg.setUserId(req.getUserPO().getId());
            msg.setTemplateId(templateId);
            msg.setSubTime(date);
            msg.setActivityName(activityInfo.getName());
            msg.setUnionId(req.getUserPO().getUnionId());
            if (!"jinshuju".equals(activityInfo.getType())) {
                msg.setNickName(req.getUserPO().getNickName());
                if (Objects.nonNull(userParticipateActivityInfo)) {
                    msg.setMobile(userParticipateActivityInfo.getMobile());
                }
            } else {
                //金数据类型活动
                msg.setMobile(req.getUserPO().getMobile());
            }
            // 设置授权的appId和openId
            msg.setAuthAppId(req.getAppId());
            msg.setAuthOpenId(req.getOpenId());
            userActivitySubWechatTemplateMsgService.create(msg);

        }
        if (TaskBizType.SUBSCRIPTION.equals(req.getTaskBizType()) || Objects.nonNull(taskInfo)) {
            this.join(req.getUserPO(), req.getActivityId(), TaskBizType.SUBSCRIPTION);
        }
        return true;
    }

    @Override
    public boolean subsriptionAppWechatMsg(@NotNull SubsriptionWechatMsg req) {
        log.info(":>>> 开始处理平台级别订阅消息:{}", JSON.toJSONString(req));
        boolean subscribed = userAppSubWechatTemplateMsgService.subscribed(req.getUserPO().getId(), req.getPlatform(), req.getAppId());
        if (subscribed) {
            throw new BusinessException("请不要重复订阅");
        }
        Date date = new Date();
        Boolean isSub = false;
        for (String templateId : req.getTemplateIds()) {
            UserAppSubWechatTemplateMsg msg = new UserAppSubWechatTemplateMsg();
            msg.setAppId(req.getAppId());
            msg.setPlatform(req.getPlatform());
            msg.setTaskId("");
            msg.setUserId(req.getUserPO().getId());
            msg.setTemplateId(templateId);
            msg.setSubTime(date);
            msg.setOpenId(req.getUserPO().getOpenId());
            msg.setUnionId(req.getUserPO().getUnionId());
            msg.setEmail(req.getUserPO().getEmail());
            msg.setMobile(req.getUserPO().getMobile());
            msg.setNickName(req.getUserPO().getNickName());
            msg.setAvatarUrl(req.getUserPO().getAvatarUrl());
            Boolean isCreated = userAppSubWechatTemplateMsgService.create(msg);
            if (isCreated && !isSub) {
                isSub = true;
            }
        }
//        this.join(req.getUserPO(), req.getActivityId(), TaskBizType.SUBSCRIPTION);

        if (isSub) {
            Integer point = pointPlatformConfigService.getPoint(req.getAppId(), "subscription");
            UserPointsDetail detail = new UserPointsDetail();
            detail.setUserId(req.getUserPO().getId());
            detail.setAction("add");
            detail.setBizDesc("订阅通知");
            detail.setBizType("subscription");
            detail.setOptDate(new Date());
            detail.setPoints(point);
            detail.setComments("订阅通知");
            detail.setPlatform(req.getPlatform());
            detail.setAppId(req.getAppId());
            userPointsService.addPoint(detail);
        }
        return true;
    }

    @Override
    public boolean subWechatMsg(SubsriptionWechatMsg req) {
        Date date = new Date();
        for (String templateId : req.getTemplateIds()) {
            UserAppSubWechatTemplateMsg msg = new UserAppSubWechatTemplateMsg();
            msg.setAppId(req.getAppId());
            msg.setPlatform(req.getPlatform());
            msg.setTaskId("");
            msg.setUserId(req.getUserPO().getId());
            msg.setTemplateId(templateId);
            msg.setSubTime(date);
            msg.setOpenId(req.getUserPO().getOpenId());
            msg.setUnionId(req.getUserPO().getUnionId());
            msg.setEmail(req.getUserPO().getEmail());
            msg.setMobile(req.getUserPO().getMobile());
            msg.setNickName(req.getUserPO().getNickName());
            msg.setAvatarUrl(req.getUserPO().getAvatarUrl());
            userAppSubWechatTemplateMsgService.create(msg);
        }
        //添加订阅记录
        UserSubActivity activity = mongoTemplate.findOne(new Query(Criteria.where("activityId").is(req.getActivityId())
                .and("userId").is(req.getUserPO().getId())), UserSubActivity.class);
        if (activity == null) {
            activity = new UserSubActivity();
            activity.setActivityId(req.getActivityId());
            activity.setUserId(req.getUserPO().getId());
            activity.setSubStatus(1);
            mongoTemplate.insert(activity);
        }
        return true;
    }

    @Override
    public ActivityTaskCaDomain getActivityTaskCaInfo(QueryQaHomeCommand req) {
        //活动ID
        ActivityTaskCaDomain userCompetitionQa = new ActivityTaskCaDomain();
        String activityId = req.getActivityGroupId();
        UserPO currentUser = req.getCurrentUser();
        String userId = req.getCurrentUser().getId();
        userCompetitionQa.setUserId(userId);
        userCompetitionQa.setActivityId(activityId);
        userCompetitionQa.setNickName(currentUser.getNickName());
        userCompetitionQa.setAvatarUrl(currentUser.getAvatarUrl());
        ActivityInfo activityInfo = this.activityService.findOne(activityId);
        userCompetitionQa.setQaExercise(activityInfo.getQaExercise());
        userCompetitionQa.setActivityType(activityInfo.getType());
        userCompetitionQa.setHasPaperCa(activityInfo.getHasPaperCa());
        userCompetitionQa.setHasElectronicCa(activityInfo.getHasElectronicCa());
        userCompetitionQa.setDigitalCaReceive(activityInfo.getDigitalCaReceive());
        userCompetitionQa.setDigitalCaNoReceiveDesc(activityInfo.getDigitalCaNoReceiveDesc());
        UserParticipateActivityInfo userParticipateActivityInfo =
                this.userParticipateActivityInfoService.findByUserIdActivityId(userId, activityId);
        if (Objects.nonNull(userParticipateActivityInfo)) {
            userCompetitionQa.setName(userParticipateActivityInfo.getName());
            userCompetitionQa.setUniversityId(userParticipateActivityInfo.getUniversityId());
            userCompetitionQa.setUniversityName(userParticipateActivityInfo.getUniversityName());
        }
        List<UserCa> userCaList = userCaService.findByUserIdAndActivityIdAndTaskBizType(userId, activityId, "ganwu");
        if (CollectionUtils.isNotEmpty(userCaList)) {
            if (Objects.nonNull(userCaList.get(0))) {
                String caType = userCaList.get(0).getCaType();
                userCompetitionQa.setQaType(caType);
                userCompetitionQa.setCaType(caType);
                userCompetitionQa.setCaLevel(userCaList.get(0).getCaLevel());
                userCompetitionQa.setReceiveCa(Boolean.TRUE);
                userCompetitionQa.setTips("恭喜获得" + userCaList.get(0).getCaLevel());
                //领取电子版需要收费
                if (activityInfo.getContestDigitalCaFee() > 0) {
                    userCompetitionQa.setDigitalCaPay(Boolean.TRUE);
                    userCompetitionQa.setDigitalCaPayDesc(activityInfo.getDigitalCaPayDesc());
                }
            } else {
                userCompetitionQa.setCaLevel("暂无等级");
                userCompetitionQa.setTips("很遗憾！暂不能获得证书");
            }
        } else {
            userCompetitionQa.setTips("很遗憾！暂不能获得证书");
        }
        log.info(":>>> 用户:{},证书领取信息:{}", JSON.toJSON(req), JSON.toJSON(userCompetitionQa));
        return userCompetitionQa;
    }

    @Override
    public UserActivityTaskInfo submitGanWu(String activityId, UserPO userPO, TaskBizType taskBizType) {
        log.info(":>>> 开始提交感悟:{},{},{}", activityId, taskBizType, JSON.toJSON(userPO));
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("taskBizType").is(taskBizType).and("userId").is(userPO.getId()));
        UserActivityTaskInfo taskInfo = mongoTemplate.findOne(query, UserActivityTaskInfo.class);
        Query queryUp = new Query();
        queryUp.addCriteria(Criteria.where("userId").is(userPO.getId()).and("activityId").is(activityId).and("joined").is(Boolean.TRUE));
        UserParticipateActivityInfo up = mongoTemplate.findOne(queryUp, UserParticipateActivityInfo.class);
        log.info(":>>> 活动:{},用户报名信息:{}",activityId,JSON.toJSON(up));
        if (Objects.isNull(taskInfo)) {
            taskInfo = new UserActivityTaskInfo();
            taskInfo.setActivityId(activityId);
            taskInfo.setUserId(userPO.getId());
            taskInfo.setTaskBizType(taskBizType);
            taskInfo.setCreatedTime(new Date());
//            taskInfo.setAppId("");
//            taskInfo.setPlatform("");
            // 1:待审核
            taskInfo.setStatus(1);
            if (Objects.nonNull(up)) {
                taskInfo.setName(up.getName());
                taskInfo.setUniversityId(up.getUniversityId());
                taskInfo.setUniversityName(up.getUniversityName());
                taskInfo.setMobile(up.getMobile());
            }
            taskInfo = mongoTemplate.insert(taskInfo);
            return taskInfo;
        }
//        if (1 == taskInfo.getStatus()) {
//            return taskInfo;
//        }
        Update update = new Update();
        update.set("status", 1);
        update.set("updatedTime", new Date());
        if (Objects.nonNull(up)) {
            update.set("name", up.getName());
            update.set("universityId", up.getUniversityId());
            update.set("universityName", up.getUniversityName());
            update.set("mobile", up.getMobile());
        }
        mongoTemplate.updateFirst(query, update, UserActivityTaskInfo.class);
        taskInfo.setStatus(1);
        return taskInfo;
    }

    @Override
    public UserActivityTaskInfo findUserActivityTaskInfo(String activityId, UserPO userPO, TaskBizType taskBizType) {
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId).and("taskBizType").is(taskBizType.name()).and("userId").is(userPO.getId()));
        return mongoTemplate.findOne(query, UserActivityTaskInfo.class);
    }

    @Override
    public UserActivityTaskInfo findOne(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        UserActivityTaskInfo u = mongoTemplate.findOne(query, UserActivityTaskInfo.class);
        if (Objects.nonNull(u)) {
            if (StringUtils.isNotBlank(u.getUserId()) && StringUtils.isNotBlank(u.getActivityId()) && Objects.nonNull(u.getTaskBizType())) {
                Query queryPrint = new Query();
                queryPrint.addCriteria(Criteria.where("userId").is(u.getUserId()).and("activityId").is(u.getActivityId())
                        .and("taskBizType").is(u.getTaskBizType().name()));
                queryPrint.limit(10);
                List<UserActivityFootPrint> list = mongoTemplate.find(queryPrint, UserActivityFootPrint.class);
                u.setPrints(list);
            }
        }
        return u;
    }

    @Override
    public boolean verifyTask(UserActivityTaskInfoVerifyReq req) {
        log.info(":>>> 开始审核任务:{}", JSON.toJSON(req));
        UserActivityTaskInfo u = findOne(req.getId());
        if (Objects.isNull(u)) {
            log.error(":>>>  用户活动任务不存在:{}", req.getId());
            throw new BusinessException("用户活动任务不存在");
        }
        /**
         * 状态,0:待上传,1:待审核,2:审核通过,3:审核不通过,4:已领取
         */
        if (CollectionUtils.isNotEmpty(req.getPrints())) {
            this.getPrintsStatus(req.getPrints(),
                    u.getActivityId(), u.getTaskBizType(),
                    u.getUserId());
        }
//        if (Objects.nonNull(u.getStatus()) && 1 != u.getStatus()) {
//            return false;
//        }
        UserParticipateActivityInfo up = null;
        if (StringUtils.isBlank(u.getMobile()) || StringUtils.isBlank(u.getName()) || StringUtils.isBlank(u.getUniversityId())) {
            up = userParticipateActivityInfoService.findBy(u.getActivityId(), u.getUserId());
        }
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(u.getActivityId(), TaskBizType.SHOW_STYLE);
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        update.set("status", req.getStatus());
        update.set("verifyComment", req.getVerifyComment());
        update.set("updatedTime", new Date());
        if (Objects.nonNull(up)) {
            if (StringUtils.isBlank(u.getName())) {
                update.set("name", up.getName());
            }
            if (StringUtils.isBlank(u.getMobile())) {
                update.set("mobile", up.getMobile());
                u.setMobile(up.getMobile());
            }
            if (StringUtils.isBlank(u.getUniversityId())) {
                update.set("universityId", up.getUniversityId());
            }
            if (StringUtils.isBlank(u.getUniversityName())) {
                update.set("universityName", up.getUniversityName());
            }
        }
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, UserActivityTaskInfo.class);
        boolean updateR = updateResult.getModifiedCount() > 0 ? true : false;
        if (updateR && 2 == req.getStatus()) {
            ActivityInfo activityInfo = activityService.findOne(u.getActivityId());
            Query queryUserCa = new Query();
            queryUserCa.addCriteria(Criteria.where("userId").is(u.getUserId()).
                    and("activityId").is(u.getActivityId()).and("taskBizType").is("ganwu"));
            boolean exist = mongoTemplate.exists(queryUserCa, UserCa.class);
            log.info(":>>> 用户:{},活动:{},感悟类证书是否存在:{}", u.getUserId(), u.getActivityId(), exist);
            if (!exist) {
                UserCa userCa = new UserCa();
                CertificateActivityConfig certificateActivityConfig = certificateActivityConfigService.findByActivityIdAndBizType(u.getActivityId(),
                        activityInfo.getCaMatchKeyWords().get("ganwu"));
                if (Objects.nonNull(certificateActivityConfig)) {
                    userCa.setCertificateActivityConfigId(certificateActivityConfig.getId());
                    userCa.setCaType(certificateActivityConfig.getCaType());
                    userCa.setCertificateName(certificateActivityConfig.getCertificateName());
                }
                if (StringUtils.isNotBlank(activityTaskInfo.getCaGroupName())) {
                    userCa.setCaLevel(activityTaskInfo.getCaGroupName());
                } else {
                    userCa.setCaLevel("读书达人");
                }
                userCa.setActivityId(u.getActivityId());
                userCa.setMoneyType("3");
                userCa.setActivityName(activityInfo.getName());
                UserParticipateActivityInfo userInfoExtend = userParticipateActivityInfoService.findBy(u.getActivityId(), u.getUserId());
                //获取用户信息
                if (Objects.nonNull(userInfoExtend)) {
                    userCa.setUniversityId(userInfoExtend.getUniversityId());
                    userCa.setUniversityName(userInfoExtend.getUniversityName());
                    userCa.setName(userInfoExtend.getName());
                    userCa.setMobile(userInfoExtend.getMobile());
                    userCa.setGrade(userInfoExtend.getGrade());
                }
                userCa.setTaskBizType("ganwu");
                userCa.setUserId(u.getUserId());
                userCa.setScore(0D);
                userCa.setPlatform(u.getPlatform());
                userCa.setAppId(u.getAppId());
                //生成用户证书信息
                userCaService.create(userCa);
            }

        }
        // 开始发送短信
        if (updateR) {
            ActivityInfo activityInfo = activityService.findOne(u.getActivityId());
            this.sendSms(activityInfo.getSmsSign(),
                    u.getMobile(),
                    req.getStatus(), "" + activityTaskInfo.getApprovePassSmsTemplateId(),
                    "" + activityTaskInfo.getApproveNotPassSmsTemplateId());
        }
        return updateR;
    }

    private Integer getPrintsStatus(List<UserActivityFootPrint> prints,
                                    String activityId, TaskBizType taskBizType,
                                    String userId) {
        for (UserActivityFootPrint u : prints) {
            Query query = new Query();
            query.addCriteria(Criteria.where("id").is(u.getId()));
            Update update = new Update();
            update.set("status", u.getStatus());
            update.set("updatedTime", new Date());
            mongoTemplate.updateFirst(query, update, UserActivityFootPrint.class);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId).and("activityId").is(activityId).
                and("taskBizType").is(taskBizType));
        Long count = mongoTemplate.count(query, UserActivityFootPrint.class);
        query.addCriteria(Criteria.where("status").is(1));
        Long countPass = mongoTemplate.count(query, UserActivityFootPrint.class);
        /**
         * 状态,0:待审核,1:审核通过,2:驳回,3:无提交
         */
        if (count.compareTo(countPass) == 0) {
            return 1;
        } else if (count.compareTo(countPass) == 1) {
            return 0;
        } else {
            return 3;
        }
    }

        private void sendSms(String sign,
                         String mobile,
                         Integer status, String templateId1, String templateId2) {
        try {
            SmsBaseInfoDTO smsBaseInfoDTO = SmsBaseInfoDTO.builder().phone(mobile).build();
            String[] contents = {"读书感悟"};
            smsBaseInfoDTO.setTemplateParamSet(contents);
            smsBaseInfoDTO.setSignName(sign);
            switch (status) {
                // 审核通过
                case 2:
                    smsBaseInfoDTO.setTemplateId(templateId1);
                    break;
                // 审核不通过
                case 3:
                    smsBaseInfoDTO.setTemplateId(templateId2);
                    break;
                default:
                    break;
            }
            smsBaseInfoDTO.setSmsType(SmsBaseInfoDTO.SmsType.SMS_TEM);
            smsServerService.sendSmsMsg(smsBaseInfoDTO);
        } catch (Exception e) {
            log.error(":>>> 发送短信错误:{}", e);
        }
    }
}
